package com.example.opengldemo.jbulletJava;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.opengl.GLES30;
import android.view.View;

import com.bulletphysics.collision.dispatch.CollisionFlags;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.shapes.*;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;

import javax.vecmath.Vector3f;

public class LandForm {

    TextureRect textureRect ;

    public LandForm(View mv, final float UNIT_SIZE, float yOffset,
                    DiscreteDynamicsWorld dynamicsWorld,
                    float[][] yArray, int rows, int cols, int mProgram) {
        textureRect = new TextureRect() ;
        textureRect.initShader(mProgram);
        int vCount = cols * rows * 2 * 3;
        float vertices[] = new float[vCount * 3];
        int count = 0;
        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < cols; i++) {

                float zsx = -UNIT_SIZE * cols / 2 + i * UNIT_SIZE;
                float zsz = -UNIT_SIZE * rows / 2 + j * UNIT_SIZE;

                vertices[count++] = zsx;
                vertices[count++] = yArray[j][i] + yOffset;
                vertices[count++] = zsz;

                vertices[count++] = zsx;
                vertices[count++] = yArray[j + 1][i] + yOffset;
                vertices[count++] = zsz + UNIT_SIZE;

                vertices[count++] = zsx + UNIT_SIZE;
                vertices[count++] = yArray[j][i + 1] + yOffset;
                vertices[count++] = zsz;

                vertices[count++] = zsx + UNIT_SIZE;
                vertices[count++] = yArray[j][i + 1] + yOffset;
                vertices[count++] = zsz;

                vertices[count++] = zsx;
                vertices[count++] = yArray[j + 1][i] + yOffset;
                vertices[count++] = zsz + UNIT_SIZE;

                vertices[count++] = zsx + UNIT_SIZE;
                vertices[count++] = yArray[j + 1][i + 1] + yOffset;
                vertices[count++] = zsz + UNIT_SIZE;
            }
        }
        textureRect.setVertexBuffer(vertices);
        textureRect.setTexCoorBuffer(generateTexCoor(cols, rows));

        //创建为凹凸地形碰撞形状服务的顶点数据缓冲
        ByteBuffer gVertices = ByteBuffer.allocateDirect(vCount * 3 * 4).order(ByteOrder.nativeOrder());
        for (int i = 0; i < vertices.length; i++) {
            gVertices.putFloat(i * 4, vertices[i]); // x , x , x , x  第一个x是顶点数据
        }
        gVertices.position(0);

        ByteBuffer gIndices = ByteBuffer.allocateDirect(vCount * 4).order(ByteOrder.nativeOrder());
        for (int i = 0; i < vCount; i++) {
            gIndices.putInt(i);   // 前vCount 数 是 大小
        }
        gIndices.position(0);

        int vertStride = 4 * 3;
        int indexStride = 4 * 3;
        // 按照索引的三角行 碰撞
        TriangleIndexVertexArray indexVertexArrays =
                new TriangleIndexVertexArray
                        (
                                vCount / 3,
                                gIndices,
                                indexStride,
                                vCount,
                                gVertices,
                                vertStride
                        );

        CollisionShape groundShape = new BvhTriangleMeshShape(indexVertexArrays, true, true);


        Transform groundTransform = new Transform();
        groundTransform.setIdentity();
        groundTransform.origin.set(new Vector3f(0.f, 0.f, 0.f));
        Vector3f localInertia = new Vector3f(0, 0, 0);

        DefaultMotionState myMotionState = new DefaultMotionState(groundTransform);

        RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(0, myMotionState, groundShape, localInertia);

        RigidBody body = new RigidBody(rbInfo);

        body.setRestitution(0.4f);

        body.setFriction(0.8f);
        body.setCollisionFlags(body.getCollisionFlags() & ~CollisionFlags.KINEMATIC_OBJECT);
        body.forceActivationState(CollisionObject.ACTIVE_TAG);

        dynamicsWorld.addRigidBody(body);

    }


    public void drawSelf(int texId) {
        textureRect.drawSelf(texId);
    }


    public float[] generateTexCoor(int bw, int bh) {
        float[] result = new float[bw * bh * 6 * 2];
        float sizew = 16.0f / bw;
        float sizeh = 16.0f / bh;
        int c = 0;
        for (int i = 0; i < bh; i++) {
            for (int j = 0; j < bw; j++) {

                float s = j * sizew;
                float t = i * sizeh;

                result[c++] = s;
                result[c++] = t;

                result[c++] = s;
                result[c++] = t + sizeh;

                result[c++] = s + sizew;
                result[c++] = t;


                result[c++] = s + sizew;
                result[c++] = t;

                result[c++] = s;
                result[c++] = t + sizeh;

                result[c++] = s + sizew;
                result[c++] = t + sizeh;
            }
        }
        return result;
    }
}
